### Copyright (C) 2010 Desmond Carter
###
### This file is part of Ar.
###
### Ar is free software: you can redistribute it and/or modify it under the
### terms of the GNU General Public License as published by the Free Software
### Foundation, either version 3 of the License, or (at your option) any later
### version.
###
### Ar is distributed in the hope that it will be useful, but WITHOUT ANY
### WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
### FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
### details.
###
### You should have received a copy of the GNU General Public License along
### with Ar. If not, see <http://www.gnu.org/licenses/>.

## This file is for defining functions used in drawing and their important back
## ends that handle projection. (Note that projection is currently isometric; I
## want to eventually switch to OpenGL for perspective, but I can't figure it
## out yet.)

import pygame, ar
from locals import *

# The most important draw function; it handles projection from the 3d board to
# the 2d screen. It is currently isometric; I'm working on fixing that, but
# its priority is disproportionately low.
def board_to_screen(point, origin=origin):
    '''Find the point on the screen to which the point on the board should be
    mapped.
    point should be at most three dimensions; non-visible dimensions have no
    effect on the mapping.'''

    ar.board2screencount += 1
    if False:#len(point) <= 2:
        print point, "at", ar.board2screencount

    x = origin[0] + scale*point[0]
    try: # Wrap it in try...except so it doesn't fail on singleton sequences
        y = origin[1] - scale*point[1]
    except IndexError:
        y = origin[1] # There was no point[1]
        
    if len(point) == 3: # translate it diagonally
        x += scale*point[2]*SHRINK
        y -= scale*point[2]*SHRINK

    return (int(x), int(y))



def project_line(start, end, screen=ar.screen, origin=ar.origin, color=WHITE,
                 width=1):
    '''Project a line from a 3-space to the screen.'''

    pygame.draw.line(screen, color,
                     board_to_screen(start, origin),
                     board_to_screen(end, origin),
                     width)



def clear(screen=ar.screen):
    screen.fill((0, 0, 0, 255))



# This is still 2d scrolling; fixing this is *deservedly* low-priority.
# There is also a bug in which the origin moves further than the screen scrolls
# (at least I *think* that's the problem); fixing this is my current goal.
def scroll(dx=0, dy=0, screen=ar.screen, origin=origin):
    doboth(clear, screen=ar.screen, value=ar.background)
    #screen.scroll(dx, -dy)
    # Can't seem to use doboth here
    screen.scroll(dx, -dy)
    background.scroll(dx, -dy)

    # Move the origin the same distance in the opposite direction. This doesn't
    # appear to be working.
    ar.origin[0] += dx
    ar.origin[1] -= dy

    # This doesn't really belong here, but I'm not sure where else to put it to
    # make the board stay drawn after scrolling.
    doboth(ar.board.draw, origin=ar.origin, screen=ar.screen,
           drawn_dimensions=ar.drawn_dimensions)


# This is a really weird, not-very-intuitive function that should be replaced
# with something better (or scrapped entirely) as soon as I figure out what I
# want it to do.
# Note also that it doesn't seem to be working correctly. I am not sure why
# this is.
def doboth(function, parameter='screen', value=ar.background, **args):
    '''Though there are countless ways in which it could be used/abused, the
    primary purpose of this function is to draw to the screen and background
    simultaneously.'''

    function(**args) # You can pass arbitrary arguments to function as long as
                     # they're keywords

    args[parameter] = value # by default, "args['screen'] = ar.background"

    function(**args) # call it again with other arguments the same
